using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace DCApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            
        }


        private void Form_Load(object sender, EventArgs e)
        {
            SetupDataGridView();
            BindGridFromXmlStore();


            //When the application is run, make sure the user has gone thru the 
            //process of creating a new application id and setting the app.config
            //with that value.  If App.config does not have the application id prompt the 
            //user to go thru the application id creation process.
            if (String.IsNullOrEmpty(DCHelper.Functions.ApplicationId))
            {
                string message = "Before you can run this sample application you must generate an ApplicationID and set its value in the config file.\n";
                message += "Please see the Readme.htm file in the same directory as this executable for instructions.";

                MessageBox.Show(message, "Generate your own ApplicationID");
                this.Close();

                //Attempt to start the default browser showing the document with steps to create 
                //a new Application ID and ignore any errors during doing so
                try
                {
                    System.Diagnostics.Process.Start("Readme.htm");
                }
                catch{}
                return;
            }



            //Set the default date since when participant data needs to 
            //be downloaded to 1 month prior to today

            dateSinceToRetrieve.Value = DateTime.Now.Date.AddMonths(-1);

        }

        /// <summary>
        /// Add Columns to the grid view and set the styles
        /// </summary>
        private void SetupDataGridView()
        {
            //Add the 4 visible columns and one hidden column.
            //At runtime, for each row, this hidden column cell will have the currently 
            //bound ApplicationSpecificPartcipantId for the row in the "Value" property
            
            DataGridViewCheckBoxColumn select_column = new DataGridViewCheckBoxColumn();
            DataGridViewTextBoxColumn name_column = new DataGridViewTextBoxColumn();
            DataGridViewTextBoxColumn status_column = new DataGridViewTextBoxColumn();
            DataGridViewButtonColumn more_info_column = new DataGridViewButtonColumn();
            DataGridViewTextBoxColumn hidden_partcipantid_column = new DataGridViewTextBoxColumn();

            select_column.Name = "Select";
            name_column.Name = "Name";
            status_column.Name = "HasAuthorized";
            more_info_column.Name = "Details";
            hidden_partcipantid_column.Name = "MyAppSpecificParticipantId";


            hidden_partcipantid_column.Visible = false;

            //All the columns except the select column is read only
            select_column.ReadOnly = false;
            name_column.ReadOnly = true;
            status_column.ReadOnly = true;
            more_info_column.ReadOnly = false;
            
            more_info_column.CellTemplate.Style.Padding = new Padding(2);

            //Add the 5 columns to the grid view
            participantGridView.Columns.Add(select_column);
            participantGridView.Columns.Add(name_column);
            participantGridView.Columns.Add(status_column);
            participantGridView.Columns.Add(more_info_column);
            participantGridView.Columns.Add(hidden_partcipantid_column);

        }

        /// <summary>
        /// This function populates the current data stored in XML to the grid
        /// </summary>
        private void BindGridFromXmlStore()
        {
            //Clear all rows first
            participantGridView.Rows.Clear();

            //Read XML and construct the data set from it
            DataSet ds = XmlStore.ConstructDataSetFromXml();
            
            foreach (DataRow row in ds.Tables[0].Rows)
            {
                bool bHasUserAuthorizedApplication = ((bool)row["HasAuthorized"] == true);

                //Construct the data for the 5 columns that the grid has
                object [] rowData = new object[5];

                if (bHasUserAuthorizedApplication)
                {
                    //For participants who has authorized the application, show checked check box 
                    //so that user can select / unselect this row 
                    rowData[0] = true;  
                }
                else
                {
                    //For participants who has not authorized the application, do not
                    //show the check box since we cant access their healthvault record yet
                    rowData[0] = null;  
                }
                
                rowData[1] = row["ParticipantName"];
                rowData[2] = row["HasAuthorized"];
                rowData[3] = "View/Print";
                rowData[4] = row["MyAppSpecificParticipantId"];

                //Add a row to grid
                int rowIndex = participantGridView.Rows.Add(rowData);

                //If the user has not authorized the application, make sure 
                //the check box is readonly and cannot be checked.
                if (!bHasUserAuthorizedApplication)
                {
                    participantGridView.Rows[rowIndex].Cells["Select"].ReadOnly = true;
                }
                else
                {
                    participantGridView.Rows[rowIndex].Cells["Select"].ReadOnly = false;
                }
            }
            return;
        }

        private void Enroll_Click(object sender, EventArgs e)
        {
            EnrollDlg enrollDlg = new EnrollDlg();
            DialogResult dlgResult = enrollDlg.ShowDialog(this);
            if (dlgResult == DialogResult.OK)
            {
                //When we add a participant make sure we refresh the grid
                BindGridFromXmlStore();

                //Show the participant details so that the it can be printed
                //and handed over to the participant
                ParticipantDlg participantDlg = new ParticipantDlg();
                participantDlg.AppSpecificParticpantId = enrollDlg.AppSpecificParticpantId;
                participantDlg.ShowDialog(this);
            }
            
        }



        private void Grid_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            //We need to hide DataGridViewCheckBoxCell (Select column) on some rows of the 
            //DataGridView. There is no direct way to do that. Hence override the painting
            //for that cell and do not draw it if the value (DataGridViewCheckBoxCell.Value) 
            //is null.

            if (e.RowIndex == -1)
            {
                //Dont do anything fancy for headers
                return;
            }


            DataGridViewCell cell = participantGridView.Rows[e.RowIndex].Cells[e.ColumnIndex];
            if (cell.GetType() == typeof(DataGridViewCheckBoxCell))
            {
                //About to draw a DataGridViewCheckBoxCell
                DataGridViewCheckBoxCell chkCell = (DataGridViewCheckBoxCell)cell;
                if (chkCell.Value == null)
                {
                    e.PaintBackground(e.ClipBounds, true);
                    e.Handled = true;
                }
            }
        }

        private void btnSelectAll_Click(object sender, EventArgs e)
        {

            //For each row where DataGridViewCheckBoxCell is visible, make it checked
            foreach(DataGridViewRow gRow in participantGridView.Rows)
            {
                if ((gRow.Cells[0] as DataGridViewCheckBoxCell).Value != null)
                {
                    (gRow.Cells[0] as DataGridViewCheckBoxCell).Value = true;
                }
            }

        }

        private void btnSelectNone_Click(object sender, EventArgs e)
        {
            //For each row where DataGridViewCheckBoxCell is invisible, make it unchecked
            foreach (DataGridViewRow gRow in participantGridView.Rows)
            {
                if ((gRow.Cells[0] as DataGridViewCheckBoxCell).Value != null)
                {
                    (gRow.Cells[0] as DataGridViewCheckBoxCell).Value = false;
                }
            }
        }

        private void Grid_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            //Trap the cell click function to handle the button clicks
            //when the user clicks the "View/Print" button on the grid

            if (e.RowIndex == -1)
            {
                //Ignore if the header is clicked
                return;
            }

            DataGridViewCell cell = participantGridView.Rows[e.RowIndex].Cells[e.ColumnIndex];
            if (cell.GetType() == typeof(DataGridViewButtonCell))
            {
                //Button cell clicked
                DataGridViewButtonCell btnCell = (DataGridViewButtonCell)cell;

                //Find the application specific participant id for the row from the 
                //corresponding hidden column cell - MyAppSpecificParticipantKey
                string myAppSpecificParticipantId = btnCell.OwningRow.Cells["MyAppSpecificParticipantId"].Value.ToString();


                //Show the participant details
                ParticipantDlg participantDlg = new ParticipantDlg();
                participantDlg.AppSpecificParticpantId = myAppSpecificParticipantId;
                DialogResult dlgResult = participantDlg.ShowDialog(this);
            }

        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            CheckStatusDlg checkStatusDlg = new CheckStatusDlg();
            DialogResult dlgResult = checkStatusDlg.ShowDialog(this);
            
            //Rebind the grid from store again so that it will show the latest status
            BindGridFromXmlStore();
        }

        private void btnRetrieve_Click(object sender, EventArgs e)
        {

            btnRetrieve.Text = "Processing...";
            btnRetrieve.Enabled = false;

            Application.DoEvents();


            try
            {

               

                //Construct a list of participants whose data needs to be retrieved
                List<DCHelper.ParticipantConnectionDetails> participantConnectionDetailsList = new List<DCHelper.ParticipantConnectionDetails>();

                foreach (DataGridViewRow gRow in participantGridView.Rows)
                {
                    //If a row is checked (ie, value of cell is true) add it to list
                    DataGridViewCheckBoxCell select_cell = (gRow.Cells[0] as DataGridViewCheckBoxCell);
                    if (select_cell.Value != null && ((bool)select_cell.Value) == true)
                    {
                        string myAppSpecificParticipantId = gRow.Cells["MyAppSpecificParticipantId"].Value.ToString();

                        DataRow row = XmlStore.FetchParticipantFromLocalStore(myAppSpecificParticipantId);

                        Guid personId = new System.Guid(row["PersonId"].ToString());
                        Guid recordId = new System.Guid(row["RecordId"].ToString());

                        DCHelper.ParticipantConnectionDetails connectionDetail = new DCHelper.ParticipantConnectionDetails(myAppSpecificParticipantId, personId, recordId);
                        participantConnectionDetailsList.Add(connectionDetail);
                    }

                }

                if (participantConnectionDetailsList.Count == 0)
                {
                    MessageBox.Show("No participants selected. Please select one or more participants whose data needs to be retrieved");
                    return;
                }

                //One or more participants selected. Initialize results dialog and Show it
                //The actual retrieve of data will be done by that dialog

                int totalParticipants = participantGridView.Rows.Count;
                ResultsDlg resultsDlg = new ResultsDlg(totalParticipants, this.dateSinceToRetrieve.Value, participantConnectionDetailsList);

                resultsDlg.ShowDialog();
                
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Exception occured:" + ex.Message);
            }
            finally
            {
                btnRetrieve.Text = "&Retrieve Data";
                btnRetrieve.Enabled = true;

               
            }
        }
    }
}